//
// Created by twetec on 25-8-16.
//

#ifndef NETWORK_PROBER_PROBE_DETECT_HANDLE_SQLSERVER_PROBE_DETECT_H
#define NETWORK_PROBER_PROBE_DETECT_HANDLE_SQLSERVER_PROBE_DETECT_H

#include <future>

namespace boost::json
{
struct value_from_tag;
struct value;
}

namespace network_prober::probe_detect
{
/**
 * SQLServer IPv4 探测结果
 */
struct SQLServerProbeDetectResultIPv4
{
    std::string interface;
    std::string target;
    std::uint16_t port;
    std::int64_t delay;
};

/**
 * SQLServer 探测结果 序列化
 * 注：保证 tag_invoke函数 与 SQLServerProbeDetectResult类 在同一个命名空间
 */
void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, SQLServerProbeDetectResultIPv4 const &c);

/**
 * SQLServer IPv4
 */
class HandleSQLServerProbeDetectIPv4 : public std::enable_shared_from_this<HandleSQLServerProbeDetectIPv4>
{
public:
    /**
     *  探测
     */
    void detect();

    /**
     * 探测到时回调
     */
    void setOnDetectedCallback(std::function<void(SQLServerProbeDetectResultIPv4&&)> callback);

    /**
     * @param interface 网口地址
     * @param target 目标地址
     */
    HandleSQLServerProbeDetectIPv4(
        std::string_view interface,
        std::string_view target,
        std::uint32_t port,
        std::string_view userName,
        std::string_view password,
        std::string_view databaseName,
        std::string_view queryStatement
    );

    ~HandleSQLServerProbeDetectIPv4();

private:
    std::string m_interface;
    std::string m_target;
    std::uint32_t m_port;
    std::string m_userName;
    std::string m_password;
    std::string m_databaseName;
    std::string m_queryStatement;
    std::function<void(SQLServerProbeDetectResultIPv4&&)> m_onDetectedCallback;
    std::chrono::time_point<std::chrono::steady_clock> m_detectStartTime;
    std::future<void> m_onDetectedCallbackFuture;
};

/**
 * SQLServer IPv6 探测结果
 */
struct SQLServerProbeDetectResultIPv6
{
    std::string interface;
    std::string target;
    std::uint16_t port;
    std::int64_t delay;
};

/**
 * SQLServer 探测结果 序列化
 * 注：保证 tag_invoke函数 与 SQLServer ProbeDetectResult类 在同一个命名空间
 */
void tag_invoke(boost::json::value_from_tag, boost::json::value &jv, SQLServerProbeDetectResultIPv6 const &c);

/**
 * SQLServer IPv6
 */
class HandleSQLServerProbeDetectIPv6 : public std::enable_shared_from_this<HandleSQLServerProbeDetectIPv6>
{
public:
    /**
     *  探测
     */
    void detect();

    /**
     * 探测到时回调
     */
    void setOnDetectedCallback(std::function<void(SQLServerProbeDetectResultIPv6&&)> callback);

    /**
     * @param interface 网口地址
     * @param target 目标地址
     */
    HandleSQLServerProbeDetectIPv6(
        std::string_view interface,
        std::string_view target,
        std::uint32_t port,
        std::string_view userName,
        std::string_view password,
        std::string_view databaseName,
        std::string_view queryStatement
    );

    ~HandleSQLServerProbeDetectIPv6();

private:
    std::string m_interface;
    std::string m_target;
    std::uint32_t m_port;
    std::string m_userName;
    std::string m_password;
    std::string m_databaseName;
    std::string m_queryStatement;
    std::function<void(SQLServerProbeDetectResultIPv6&&)> m_onDetectedCallback;
    std::chrono::time_point<std::chrono::steady_clock> m_detectStartTime;
    std::future<void> m_onDetectedCallbackFuture;
};

}


#endif //NETWORK_PROBER_PROBE_DETECT_HANDLE_SQLSERVER_PROBE_DETECT_H
